package com.zdlyh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zdlyh.domain.ResponseResult;
import com.zdlyh.domain.dto.UserDto;
import com.zdlyh.domain.entity.Role;
import com.zdlyh.domain.entity.User;
import com.zdlyh.domain.entity.UserRole;
import com.zdlyh.enums.AppHttpCodeEnum;
import com.zdlyh.exception.SystemException;
import com.zdlyh.service.RoleService;
import com.zdlyh.service.UserRoleService;
import com.zdlyh.service.UserService;
import com.zdlyh.mapper.UserMapper;
import com.zdlyh.utils.BeanCopyUtils;
import com.zdlyh.utils.RedisCache;
import com.zdlyh.utils.SecurityUtils;
import com.zdlyh.domain.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{
    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private RedisCache redisCache;

    @Override
    public ResponseResult getUserInfo() {
        User user = baseMapper.selectById(SecurityUtils.getUserId());
        UserVo userVo = BeanCopyUtils.copyBean(user, UserVo.class);
        return ResponseResult.okResult(userVo);
    }

    @Override
    public ResponseResult updateUserInfo(User user) {
        baseMapper.updateById(user);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult register(UserDto userDto) {
        String code = redisCache.getCacheObject(userDto.getEmail());
        if (!userDto.getEmailCode().equals(code)){
            throw new SystemException(AppHttpCodeEnum.MAIL_Code_Error);
        }
        // 对数据进行非空判断
        if (!StringUtils.hasText(userDto.getNickName())){
            throw new SystemException(AppHttpCodeEnum.NICKNAME_NOT_NULL);
        }
        if (!StringUtils.hasText(userDto.getPassword())){
            throw new SystemException(AppHttpCodeEnum.PASSWORD_NOT_NULL);
        }
        if (!StringUtils.hasText(userDto.getEmail())){
            throw new SystemException(AppHttpCodeEnum.EMAIL_NOT_NULL);
        }
        // 对数据进行查重判断
        if (nickNameExist(userDto.getNickName())){
            throw new SystemException(AppHttpCodeEnum.NICKNAME_EXIST);
        }
        if (emailExist(userDto.getEmail())){
            throw new SystemException(AppHttpCodeEnum.EMAIL_EXIST);
        }
        // 对密码进行加密
        String encode = passwordEncoder.encode(userDto.getPassword());
        userDto.setPassword(encode);
        // 存入数据库
        User user = BeanCopyUtils.copyBean(userDto, User.class);
        user.setSex("2");
        baseMapper.insert(user);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult<PageVo> getUserList(Integer pageNum, Integer pageSize, UserDto userDto) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(userDto.getUserName()),User::getUserName,userDto.getUserName())
                .eq(StringUtils.hasText(userDto.getPhonenumber()),User::getPhonenumber,userDto.getPhonenumber())
                .eq(StringUtils.hasText(userDto.getStatus()),User::getStatus,userDto.getStatus());
        Page<User> page = new Page<>(pageNum,pageSize);
        List<User> userList = baseMapper.selectPage(page, queryWrapper).getRecords();

        List<UserVo> userVos = BeanCopyUtils.copyBeanList(userList, UserVo.class);

        PageVo pageVo = new PageVo(userVos, page.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult addUser(UserDto userDto) {
        if (!StringUtils.hasText(userDto.getUserName())){
            throw new SystemException(AppHttpCodeEnum.USERNAME_NOT_NULL);
        }
        if (userNameExist(userDto.getUserName())){
            throw new SystemException(AppHttpCodeEnum.USERNAME_EXIST);
        }
        if (phonenumberExist(userDto.getPhonenumber())){
            throw new SystemException(AppHttpCodeEnum.PHONENUMBER_EXIST);
        }
        if (emailExist(userDto.getEmail())){
            throw new SystemException(AppHttpCodeEnum.EMAIL_EXIST);
        }
        String encode = passwordEncoder.encode(userDto.getPassword());
        userDto.setPassword(encode);
        User user = BeanCopyUtils.copyBean(userDto, User.class);
        baseMapper.insert(user);

        // 增加用户角色表
        Long[] roleIds = user.getRoleIds();
        if (roleIds != null && roleIds.length > 0){
            List<UserRole> sysUserRoles = Arrays.stream(roleIds)
                    .map(roleId -> new UserRole(user.getId(), roleId))
                    .collect(Collectors.toList());
            userRoleService.saveBatch(sysUserRoles);
        }
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getUserById(Long id) {
        User user = baseMapper.selectById(id);
        // 获取全部角色
        List<Role> roleList = roleService.getAllRole();
        // 获取当前用户的角色ID
        List<Long> roleIds = baseMapper.getRoleIdByUserId(id);

        UserVo1 userVo1 = new UserVo1(roleIds,user,roleList);
        return ResponseResult.okResult(userVo1);
    }

    @Override
    public ResponseResult updateUser(UserDto userDto) {
        User user = BeanCopyUtils.copyBean(userDto, User.class);
        // 清除用户角色
        LambdaQueryWrapper<UserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserRole::getUserId,user.getId());
        userRoleService.remove(queryWrapper);
        // 新增用户角色
        Long[] roleIds = user.getRoleIds();

        if (roleIds != null && roleIds.length > 0){
            List<UserRole> sysUserRoles = Arrays.stream(roleIds)
                    .map(roleId -> new UserRole(user.getId(), roleId))
                    .collect(Collectors.toList());
            userRoleService.saveBatch(sysUserRoles);
        }
        baseMapper.updateById(user);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult deleteUserById(List<Long> userIds) {
        if(userIds.contains(SecurityUtils.getUserId())){
            return ResponseResult.errorResult(500,"不能删除当前你正在使用的用户");
        }
        baseMapper.deleteBatchIds(userIds);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult changeStatus(UserDto userDto) {
        User user = BeanCopyUtils.copyBean(userDto, User.class);
        baseMapper.updateById(user);
        return ResponseResult.okResult();
    }

    private boolean emailExist(String email) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getEmail,email);
        return count(queryWrapper)>0;
    }

    private boolean nickNameExist(String nickName) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getNickName,nickName);
        return count(queryWrapper)>0;
    }

    private boolean userNameExist(String userName) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName,userName);
        return count(queryWrapper)>0;
    }

    private boolean phonenumberExist(String phonenumber) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhonenumber,phonenumber);
        return count(queryWrapper)>0;
    }
}




